/*
 *  Copyright (C) 2011 JiangHongTiao <jjurco.sk_gmail.com>
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package sk.lieskove301.jianghongtiao.liaad.prisoner.memory;

import java.util.Deque;
import java.util.Iterator;
import sk.lieskove301.jianghongtiao.liaad.prisoner.strategy.FightResultEnum;

/**
 * Date of create: May 15, 2011
 *
 * @author JiangHongTiao <jjurco.sk_gmail.com>
 * @version 2011.0515
 */
public class LearningMemory extends AbstractForgetting implements Forgetting{

    public final double OFI = 0.5;
    public final double INIT_STAB = 1;
    public final double BASE_FACTOR = 2;

    public double ofiN = OFI;
    public double initStabN = INIT_STAB;
    public double baseFactorN = BASE_FACTOR;

    public LearningMemory() {
    }

    public LearningMemory(double ofi, double initStab, double baseFactor) {
        ofiN = ofi;
        initStabN = initStab;
        baseFactorN = baseFactor;
    }

    public LearningMemory(double ofi) {
        ofiN = ofi;
    }

    private FightResultEnum countMemories(Deque<FightResultEnum> memory,boolean forB) {
        Memory i = new Memory(forB, ofiN, initStabN, baseFactorN);
        Memory he = new Memory(forB, ofiN, initStabN, baseFactorN);

        for (Iterator<FightResultEnum> it = memory.descendingIterator(); it.hasNext();) {
            FightResultEnum fightResultEnum = it.next();
            i.putMemento((fightResultEnum.binValue() & 2) == 2);
            he.putMemento((fightResultEnum.binValue() & 1) == 1);
        }
        return FightResultEnum.fromBinValue(i.isRemembered(), he.isRemembered());
    }

    public FightResultEnum countBetrayMemories(Deque<FightResultEnum> memory) {
        return countMemories(memory, false);
    }

    public FightResultEnum countCooperateMemories(Deque<FightResultEnum> memory) {
        return countMemories(memory, true);
    }

    public double getBaseFactor() {
        return baseFactorN;
    }

    public void setBaseFactor(double baseFactorN) {
        this.baseFactorN = baseFactorN;
    }

    public double getInitStab() {
        return initStabN;
    }

    public void setInitStab(double initStabN) {
        this.initStabN = initStabN;
    }

    public double getOfi() {
        return ofiN;
    }

    public void setOfi(double ofiN) {
        this.ofiN = ofiN;
    }

    public String getName() {
        return "Learning memory";
    }

    public String getLetter() {
        return "L";
    }

}
